<template>
  <div id="map-container"></div>
</template>
<script lang="ts" setup>
  import AMapLoader from '@amap/amap-jsapi-loader';
  import { onMounted, watch, reactive, computed, toRefs } from 'vue';
  import { labelsData } from './data';

  const emit = defineEmits(['complete', 'statusChange']);
  const props = defineProps({
    list: {
      type: Array,
      default: () => [],
    },
    accessList: {
      type: Array,
      default: () => [],
    },
  });
  const { list, accessList } = toRefs(props); // 定义变量
  const data = computed(() => {
    const result: object = {};
    list.value.forEach((ele: any) => {
      result[ele[state.model === 'conDistrictLayer' ? 'customerProvince' : 'customerCity']] = {
        sale: ele.count,
      };
    });
    accessList.value.forEach((ele: any) => {
      if (result[ele[state.model === 'conDistrictLayer' ? 'customerProvince' : 'customerCity']]) {
        result[
          ele[state.model === 'conDistrictLayer' ? 'customerProvince' : 'customerCity']
        ].access = ele.count;
      } else {
        result[ele[state.model === 'conDistrictLayer' ? 'customerProvince' : 'customerCity']] = {
          access: ele.count,
        };
      }
    });
    return result;
  });

  const state = reactive({
    option: {
      // 设置地图容器id
      viewMode: '2D', // 是否为3D地图模式
      center: [104.122082, 38.719192],
      zoom: 4,
      zooms: [3, 20],
      resizeEnable: true,
      // animateEnable: false,
      features: ['bg'],
      mapStyle: 'amap://styles/707bcc343f52c8402557abfe986ed02c',
      // center: [115.78, 38.68],
      lang: 'zh_cn', // 设置地图语言类型
    },
    map: null,
    AMap: null,
    conDistrictLayer: null,
    proDistrictLayer: null,
    labelDistrictLayer: null,
    proLabel: [],
    infoWindow: null,
    infoWindowContent: null,
    target: {},
    district: null,
    polylines: [],
    model: 'conDistrictLayer',
  });
  const districtLayerStyles = {
    'nation-stroke': 'rgb(34, 167, 179)',
    'coastline-stroke': 'rgb(34, 167, 179)',
    'stroke-width': 2,
    'province-stroke': 'rgb(137, 198, 224)',
    'county-stroke': 'none',
    'city-stroke': 'rgb(255, 255, 255)',
    fill: (props) => {
      // console.log(props, state.target);
      return props.adcode === state.target.adcode ? 'rgba(255, 255, 255, 0.5)' : 'rgba(0, 0, 0,.3)';
    },
  };
  onMounted(() => {
    AMapLoader.load({
      key: '4b007f695a216951a0161b3d041cede1', // 申请好的Web端开发者Key，首次调用 load 时必填
      version: '2.0', // 指定要加载的 JSAPI 的版本，缺省时默认为 1.4.15
      plugins: [],
      Loca: {
        // 是否加载 Loca， 缺省不加载
        version: '2.0.0', // Loca 版本，缺省 1.3.2
      },
    })
      .then((AMap) => {
        state.map = new AMap.Map('map-container', {
          center: [80.601, 40.32],
          zoom: 12,
          // 地图设置成 3D 模式，否则图层会失去高度信息
          viewMode: '3D',
        });
        // 行政区
        state.conDistrictLayer = new AMap.DistrictLayer({
          zIndex: 100,
          SOC: 'CHN',
          depth: 0,
          styles: districtLayerStyles,
        });
        state.proDistrictLayer = new AMap.DistrictLayer.Province({
          zIndex: 100,
          depth: 1,
          visible: false,
          styles: districtLayerStyles,
        });
        state.map.add(state.conDistrictLayer);
        state.map.add(state.proDistrictLayer);
        //
        state.district = new AMap.DistrictSearch({
          level: 'district',
          subdistrict: 1,
          extensions: 'all',
        });
        // 信息窗
        state.infoWindow = new AMap.InfoWindow({ isCustom: true, offset: [0, -10] });
        state.infoWindowContent = computed(() => {
          return `<div class="window-box">
            <span class="name">${state.target.NAME_CHN || ''}</span>
            <span>销售设备数量：${data.value[state.target.adcode]?.sale || 0}</span>
            <span>接入设备数量：${data.value[state.target.adcode]?.access || 0}</span>
            </div`;
        });
        // 地图事件
        state.map.on('complete', function () {
          state.labelDistrictLayer = new AMap.LabelsLayer({
            // 开启标注避让，默认为开启，v1.4.15 新增属性
            collision: false,
            zIndex: 5,
            // 开启标注淡入动画，默认为开启，v1.4.15 新增属性
            animation: true,
          });
          for (var i = 0; i < labelsData.length; i++) {
            var labelsMarker = new AMap.LabelMarker(labelsData[i]);
            state.proLabel.push(labelsMarker);
          }
          state.labelDistrictLayer.add(state.proLabel);
          state.map.add(state.labelDistrictLayer);
          emit('complete');
        });
        state.map.on('mousemove', (e) => {
          state.infoWindow.setPosition(e.lnglat);
        });
        state.conDistrictLayer.on('mouseover', (e) => {
          if (state.model === 'conDistrictLayer') {
            state.infoWindow.open(state.map);
            state.target = e.props || {};
          }
        });
        state.conDistrictLayer.on('mouseout', () => {
          if (state.model === 'conDistrictLayer') {
            state.target = {};
            state.infoWindow.close();
          }
        });
        state.proDistrictLayer.on('mouseover', (e) => {
          if (state.model === 'proDistrictLayer') {
            state.infoWindow.open(state.map);
            state.target = e.props || {};
          }
        });
        state.proDistrictLayer.on('mouseout', () => {
          if (state.model === 'proDistrictLayer') {
            state.target = {};
            state.infoWindow.close();
          }
        });
        state.conDistrictLayer.on('click', (e) => {
          if (e.props && state.model === 'conDistrictLayer') {
            state.infoWindow.close();
            state.model = 'proDistrictLayer';
            state.target = {};
            state.conDistrictLayer.hide();
            state.labelDistrictLayer.remove(state.proLabel);
            state.map.setCity(e.props.NAME_CHN);
            state.district.search(e.props.NAME_CHN, (status, result) => {
              state.proDistrictLayer.setAdcode(e.props.adcode);
              state.proDistrictLayer.setStyles(districtLayerStyles);
              state.proDistrictLayer.show();
              let bounds = result.districtList[0].boundaries;
              state.map.setFitView(
                bounds.map(
                  (ele) =>
                    new state.AMap.Polygon({
                      path: ele,
                    }),
                ),
                false,
                [150, 60, 60, 60],
              );
              result.districtList[0].districtList.forEach((ele) => {
                state.labelDistrictLayer.add(
                  new AMap.LabelMarker({
                    name: '',
                    position: ele.center,
                    zooms: [4, 18],
                    zIndex: 500,
                    opacity: 1,
                    text: {
                      content: ele.name,
                      direction: 'center',
                      // offset: [0, 0],
                      zooms: [3, 20],
                      style: {
                        fontSize: 10,
                        fontWeight: 'normal',
                        fillColor: '#eee',
                        strokeColor: '#88f',
                        strokeWidth: 2,
                      },
                    },
                  }),
                );
              });
            });
            emit('statusChange', e.props.adcode);
          }
        });
        state.map.on('rightclick', (e) => {
          if (state.model === 'proDistrictLayer') {
            state.target = {};
            state.model = 'conDistrictLayer';
            state.infoWindow.close();
            state.proDistrictLayer.setAdcode(100000);
            state.proDistrictLayer.hide();
            state.conDistrictLayer.show();
            state.labelDistrictLayer.clear();
            state.labelDistrictLayer.add(state.proLabel);
            state.map.setZoomAndCenter(state.option.zoom, state.option.center, false, 200);
            emit('statusChange', '');
          }
        });
      })
      .catch((e) => {
        console.log(e);
      });
  });
  watch(
    () => state.target.adcode,
    () => {
      state.infoWindow.setContent(state.infoWindowContent);
      state[state.model].setStyles(districtLayerStyles);
    },
    { deep: true },
  );
</script>

<style scoped>
  #map-container {
    padding: 0px;
    margin: 0px;
    width: 100%;
    height: 100vh;
  }
  .window-box {
    padding: 5px 10px;
    background: rgba(83, 213, 254, 0.7);
    border: 1px solid #47ebeb;
    border-radius: 5px;
    display: flex;
    flex-direction: column;
  }
</style>
